
#include <compiler.h>

#ifndef __PS2_H__
#define __PS2_H__

#define ps2_clk P3_4 // PS/2 时钟线
#define ps2_d P2_2   // PS/2 数据线

#define PS2_LED_NUM_LOCK 0x02
#define PS2_LED_CAPS_LOCK 0x04
#define PS2_LED_SCSROLL_LOCK 0x01

// 因为发送是以包为单位的，每次失败会重发整个包
// 所以数据缓冲以以下格式存放 (D:分割符 X:数据)
// DX...XDX...XDX..X
extern __xdata __at(0x0300) UINT8 PS2_TXBuffer[]; // 发送数据缓冲
extern __xdata __at(0x0140) UINT8 PS2_TX_S;       // 发送缓冲开始位置
extern __xdata __at(0x0141) UINT8 PS2_TX_E;       // 发送缓冲结束位置
extern __xdata __at(0x0142) UINT8 PS2_RXBuffer;   // 接收数据缓冲

typedef struct
{
    UINT8 type;                   // 设备区分：1键盘
    UINT8 Enable;                 // 0: 停止扫描  1: 使能
    UINT8 LED;                    // 0x04: Caps Lock;  0x02: Num Lock;  0x01:Scroll Lock
    volatile UINT16 KeyRepeat;    // 机打按键 —— 将对此按键进行重复发送
    volatile UINT16 KeyRepeatCnt; // 机打延时计数
    UINT16 KeyRepeatRate;         // 机打频率 —— 换算成ms计数
    UINT16 KeyDelay;              // 机打延时 —— 换算成ms计数
    UINT8 KeyStatus[120];         // 记录每个按键当前状态 0：释放， 1按下
    UINT8 KeyStatusTmp[120];      // 所有按键的新状态 0：释放， 1按下
    UINT8 Keymode[120];           // 每个按键的发送方法       // 0：默认，0x01:禁止断码, 0x02:禁止机打
} _PS2_KB_INFO;
extern __xdata __at(0x0400) _PS2_KB_INFO PS2_KB_INFO; // 保存键盘的状态 —— 用于同步USB端和PS/2端，让PS/2端一直以为USB端有连接

typedef struct
{
    UINT8 type;            // 设备区分：0鼠标
    UINT8 Enable;          // 0: 停止扫描  1: 使能
    UINT8 devID;           // 0x00: 标准PS/2(3键，无滚轮)  0x03:Intellimouse（3键，有滚轮） 0x04：Intellimouse扩展（5键，有滚轮）
    UINT8 mode;            // 模式：00:初始化  01：stream（有变化就发送） 02：remote（查询才发送） 03：wrap（会送字节）
    UINT8 last_mode;       // 模式： 前一模式状态
    UINT8 SamplingRate[3]; // 采样率   当前采样率，前次采样率，前前次采样率
    UINT8 Resolution;      // 分辨率  （0： 1点/mm  1： 2点/mm  2： 4点/mm  3： 8点/mm）
    UINT8 Scaling;         // 缩放比例
    UINT8 KeyStatus[5];    // 记录每个按键当前状态 0：释放， 1按下(D0~D4:左、中、右，键4，键5)
    UINT8 KeyStatusTmp[5]; // 所有每个按键的新状态 0：释放， 1按下(D0~D4:左、中、右，键4，键5)
    short Position[3];     // 记录X,Y,滚轮当前值
    UINT8 data[4];         // 按键位移数据包
} _PS2_MS_INFO;
extern __xdata __at(0x0400) _PS2_MS_INFO PS2_MS_INFO; // 保存键盘的状态 —— 用于同步USB端和PS/2端，让PS/2端一直以为USB端有连接

extern __bit ps2_dev;
extern __bit isPS2Comm;
extern UINT8 ps2_dataBuf; // 发送/接收的数据
extern UINT8 ps2_dataChk; // 奇偶校验
extern UINT8 ps2_dataBit; // 发送/接收的数据位

void InitPS2(void);
void ps2_resetDevice(void); // 复位设备
BOOL ps2_checkChangeKB(void);
BOOL ps2_checkChangeMS(void);
void ps2_kb_checkRepeatKey(void);
void ps2_copy_code(UINT8 index, UINT8 type); // 将编码复制到缓存（循环储存）
void ps2_readAndExec_KB(void);               // 检查收到的指令，并对应（键盘）
void ps2_readAndExec_MS(void);               // 检查收到的指令，并对应（鼠标）
void ps2_sendData(void);                     // 将缓存中的数据发送出去

#endif